home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / prog / asm_0_m.arj / LDIR41.ASM < prev    next >
Assembly Source File  |  1989-01-27  |  31KB  |  1,355 lines

  1.     page    74,132
  2.     title    --- ldir - list directory -
  3.  
  4. ;    LDIR (c) Copyright Vernon D. Buerg 1985-1989
  5. ;    ALL RIGHTS RESERVED.
  6.  
  7. dtantry struc                ; DTA entry returned by DOS
  8. dtarsvd db    21 dup (0)        ;  reserved
  9. dtaattr db    0            ;  attribute
  10. dtatime dw    0            ;  update time
  11. dtadate dw    0            ;  update date
  12. dtasize dw    0,0            ;  size bytes (lo,hi)
  13. dtaname db    12 dup (' ')            ;  name and ext
  14.     db    0,13,10,255        ;  stopper and print
  15. dtantry ends
  16.  
  17. argntry struc                ; Search arguments
  18. argdriv db    0,':'                   ;  drive
  19. argpath db    '\'                     ;  path delimiter
  20. argname db    64 dup (0),255        ;  path,file,ext
  21. argntry ends
  22.  
  23. tblntry struc                ; Table Entries
  24. tblattr db    0            ;  attribute
  25. tblpath db    21 dup (0)        ;  path name(s)
  26. tblname db    8 dup (' ')             ;  file name
  27. tbldot    db    ' '                     ;  delimiter
  28. tblext    db    3 dup (' ')             ;  extension
  29. tblsize db    ' 0000000 '             ; File size
  30. tbldate db    '80-01/01 '             ; Date
  31. tbltime db    ' 0:00 '                ; Time
  32. tblfatr db    3 dup (' ')             ; File attributes
  33. tblctl    db    13,10,255        ; print control chars
  34. tblntry ends
  35.  
  36. filntry struc                ; List of files in table
  37. filsub    db    0            ; -index to subdirectory name
  38. filattr db    0            ; -file attributes
  39. filtime dw    0            ; -time stamp
  40. fildate dw    0            ; -date stamp
  41. filsize dw    0,0            ; -file size
  42. filname db    12 dup ('?')            ; -asciiz file name
  43. filstop db    ?            ; -asciiz stopper
  44. filntry ends
  45.  
  46.  
  47. bios    segment at 40h        ; dos data area
  48.     org    84h        ;
  49. ega_row label    byte        ; rows on screen
  50. bios    ends
  51.  
  52. save    macro    reglist
  53.     irp    reg, <reglist>
  54.     push    reg        ; save register
  55.     endm
  56.     endm
  57.  
  58. return    macro    reglist
  59.     irp    reg, <reglist>
  60.     pop    reg        ; restore register
  61.     endm
  62.     ret            ; return to caller
  63.     endm
  64.  
  65.  
  66. cseg    segment public para 'CODE'
  67.     assume    cs:cseg, ds:cseg, es:nothing
  68.     org    100h
  69.  
  70. ldir    proc    far
  71.     mov    sp,offset local_stack_end ; Use local stack
  72.     mov    word ptr stackx,sp      ; Save stack ptr for exiting
  73.     jmp    start
  74.  
  75.     page
  76. ;
  77. ;    Data Areas, Constants, Etc.
  78.  
  79. dta_len equ    size dtantry        ; DTA length
  80. arg_len equ    size argntry        ; Argument length
  81. tbl_len equ    size tblntry        ; Disk record entry
  82. fil_len equ    size filntry        ; File description entry
  83.  
  84. tblpara equ    tbl_len/16        ; paragraphs in each table entry
  85.  
  86. depth    equ    3            ; Maximum sub-DIR nest level
  87. tab    equ    9            ; A tabbie
  88. lf    equ    10            ; Line feed
  89. cr    equ    13            ; Carriage return
  90. stopper equ    255            ; Ends print strings
  91.  
  92. curdsk    equ    19h            ;Get current disk
  93. setdta    equ    1ah            ;Set data transfer area
  94. dskspc    equ    36h            ;Get disk free space
  95. chdir    equ    3bh            ;Change directory
  96. write    equ    40h            ;Write to a file handle
  97. getpath equ    47h            ;Get current directory
  98.  
  99. stackx    dw    0            ; Entry stack pointer
  100. dirmask db    0            ; Directory flags mask
  101. errlvl    db    0            ; DOS return code
  102. _attr    db    7            ; Clear attribute
  103. _page    db    0            ; Video page
  104. _rows    db    0            ; Rows on screen
  105.  
  106. flags    db    byname            ; Command switches
  107.  byattr  equ    1            ; -attributes included
  108.  byhide  equ    2            ; -want hidden files
  109.  byclear equ    4            ; -clear screen
  110.  bydate  equ    8            ; -sort by date/time
  111.  byext     equ    10h            ; -sort by extension
  112.  byname  equ    40h            ; -sort by name
  113.  bysize  equ    80h            ; -sort by size
  114.  
  115. flags2    db    0            ; More switches
  116.  bymod     equ    01h            ; -modified files only
  117.  bywait  equ    02h            ; -wait when screen full
  118.  bybrief equ    4            ; -four up
  119.  bypath  equ    20h            ; -all paths
  120.  
  121. date    record    yr:7,mo:4,dy:5        ; Packed date
  122. time    record    hour:5,min:6,sec:5    ; Packed time
  123.  
  124. anyname db    '\????????.???',0,stopper ;Global filename.ext
  125. subdir    db    '-Dir'
  126.  
  127. count    dw    0            ; Number of files
  128. numdir    dw    0            ; Number of table entries
  129. maxdir    dw    0            ; Maximum table entries
  130. nxtdir    dw    0            ; Offset to next entry
  131. segdir    dw    0            ; Segment addr of of gotten table
  132. numbyte dw    0,0            ;Total bytes used
  133. linecnt db    0            ;Line counter for /W
  134.  
  135. ddptr    dw    0
  136.  
  137.     page
  138. ;
  139. ;    Headings and titles
  140.  
  141. titlea    db    'List DIRectory            Volume: '
  142. volname db    11 dup (' '),11 dup (' ')
  143. month    db    'mm/'
  144. day    db    'dd/'
  145. year    db    'yy '
  146. hours    db    'hh:'
  147. mins    db    'mm:'
  148. secs    db    'ss',cr,lf,stopper
  149.  
  150. more    db    '... more',stopper
  151. backsp    db    8 dup (8),stopper    ; backspace over 'more'
  152.  
  153. titleb    db    tab,tab,tab,tab,'  '    ;Command parameters
  154. titles    db    64 dup (0),stopper    ;Current directory
  155.  
  156. titlec    db    cr,lf,'Filename Ext   Bytes  -Last Change-     '
  157. titled    db    'Filename Ext   Bytes  -Last Change-'
  158. newline db    lf,cr,stopper
  159. nrmsg    db    cr,cr,2 dup (' ')       ;Ending message
  160. nrbytes db    '       0 bytes in'
  161. nrfiles db    '       0 File(s);  '
  162. nrsize    db    '       0 bytes free.',stopper
  163.  
  164.  
  165. extfcb    db    255,0,0,0,0,0        ; Extended FCB to get label
  166.     db    8            ; Attribute
  167. drivenr db    0,11 dup('?')           ; Drive number
  168.     db    2 dup(0)        ; Current block number
  169.     db    3 dup(0)        ; Logical record size
  170.     db    20 dup(0)        ; File size
  171.  
  172. temp    db    0            ; Sort exchange area
  173. origdr    db    'x:'                    ; Original drive
  174. origdir db    '\',63 dup (0)          ; and path
  175. origptr dw    origdir         ; End of orig path name
  176.  
  177. rootdir db    'x:\',0                 ; To get vol label
  178. olddate db    8 dup (0)        ;
  179. drptr    dw    offset parmdr        ;
  180.  
  181. model    tblntry <>            ; Model print line
  182.     page
  183. ;
  184. ;    Set default drive and path
  185.  
  186. start:
  187.     mov    ah,8            ; Get monitor stuff
  188.     int    10h            ;
  189.     mov    _page,0         ; -video page
  190.     mov    _attr,ah        ; -current attribute
  191.  
  192.     push    es            ; set dos data area
  193.     mov    ax,bios         ; segment address
  194.     mov    es,ax            ;
  195.     mov    al,byte ptr es:ega_row    ; dos rows on screen
  196.     mov    ah,24            ; default max rows
  197.     or    al,al            ; is row value ok?
  198.     jz    start1            ; no, use default
  199.     mov    ah,al            ; yes,
  200. start1: sub    ah,2            ; compensate for heading
  201.     mov    byte ptr _rows,ah    ; set max rows on screen
  202.     pop    es            ;
  203.  
  204.     call    switchs         ; Get program options
  205.  
  206.     mov    ah,13            ; Reset diskettes
  207.     int    21h            ;
  208.  
  209.     mov    ah,curdsk        ; Get current disk
  210.     int    21h            ;
  211.     add    al,'A'                  ;
  212.     mov    origdr,al        ; Save original drive letter
  213.     mov    rootdir,al        ;  for reading vol label
  214.     mov    parmdr,al        ;
  215.  
  216.     mov    dx,offset dta        ; Set Data Transfer Area
  217.     mov    ah,setdta        ;
  218.     int    21h            ;
  219.  
  220.     call    getparm         ; Get desired dr:path in 'parmdir'
  221.  
  222.     call    getvol            ; Get vol name, current dir in 'origdir'
  223.  
  224.     call    setarg            ; Set search argument
  225.  
  226.     call    alloc            ; Allocate table for directory
  227.  
  228.     call    clock            ; Date/time to heading
  229.  
  230.     call    getdir            ; Read the directory
  231.  
  232.     test    flags,255        ; Any sort options?
  233.     jz    nosort            ; no, display fifo dir
  234.     call    sort            ; Sort directory table
  235.  
  236. nosort:
  237.     call    print            ; Display the entries
  238.  
  239.     mov    ax,count        ; Number of files
  240.     sub    dx,dx            ;
  241.     mov    si,offset nrfiles    ;
  242.     call    format            ;
  243.  
  244.     mov    dx,numbyte        ; Total bytes used
  245.     mov    ax,numbyte+2        ;
  246.     mov    si,offset nrbytes    ;
  247.     call    format            ;
  248.  
  249.     mov    dx,offset nrmsg     ; Display summary stats
  250.  
  251. exit:    mov    sp,cs:stackx        ; Insure exiting stack
  252.     call    prints            ; Display final message
  253.  
  254. done:    mov    sp,cs:stackx        ; Insure exiting stack
  255.     mov    al,errlvl        ; Return to system
  256.     mov    ah,4ch            ; via EXIT with error level
  257.     int    21h            ;
  258.  
  259. ldir    endp
  260.  
  261.     page
  262. ;
  263. ;    Set options from command line
  264.  
  265. switchs proc    near
  266.     mov    si,82h            ; Command tail
  267.     mov    dh,flags        ; Default switches
  268.     mov    dl,flags2
  269.     sub    cx,cx
  270.     or    cl,byte ptr -2[si]    ; test parm length
  271.     jz    switch_exit        ; none, return as-is
  272.  
  273. sw1:    lodsb                ; Scan for switch
  274.     cmp    al,'/'
  275.     loopne    sw1
  276.     or    cx,cx            ; found one?
  277.     jz    switch_exit
  278.     mov    byte ptr -1[si],cr    ; Stop string here
  279.     jmp    short sw2a
  280.  
  281. switch_exit:
  282.     mov    flags,dh        ; Store new switches
  283.     mov    flags2,dl
  284.  
  285.     mov    al,dirmask        ; Current directory attribute mask
  286.     test    flags,byhide        ;  include hidden files
  287.     jz    swx1
  288.     or    al,2
  289. swx1:    test    flags,byattr        ;  include display of attributes?
  290.     jz    swx2
  291.     or    al,7
  292. swx2:    test    flags2,bypath        ;  include sub-directories?
  293.     jz    swx3
  294.     or    al,16
  295. swx3:    mov    byte ptr dirmask,al    ; Update dir search criteria
  296.     ret
  297.  
  298. sw2:    lodsb
  299.     cmp    al,'/'                  ; Another switch?
  300.     loopne    sw2
  301.     jcxz    switch_exit
  302.  
  303. sw2a:    lodsb                ; yes, get letter following
  304.     dec    cx
  305.     jle    sw3            ; missing switch
  306.  
  307. sw3:    cmp    al,'?'                  ; Help?
  308.     jne    sw4
  309.     mov    dx,offset help
  310.     jmp    exit
  311.  
  312. sw4:    and    al,0dfh         ; Make option uppercase
  313.     cmp    al,'A'                  ; Attributes?
  314.     jne    sw5
  315.     or    dh,byattr
  316. sw5:    cmp    al,'B'                  ; Brief?
  317.     jne    sw6
  318.     or    dl,bybrief
  319. sw6:    cmp    al,'C'                  ; Clear?
  320.     jne    sw7
  321.     or    dh,byclear
  322.     call    cls
  323. sw7:    cmp    al,'D'                  ; Date?
  324.     jne    sw8
  325.     or    dh,bydate
  326. sw8:    cmp    al,'X'                  ; Ext?
  327.     jne    sw9
  328.     or    dh,byext
  329. sw9:    cmp    al,'P'                  ; Paths?
  330.     jne    sw10
  331.     or    dl,bypath
  332. sw10:    cmp    al,'S'                  ; Size?
  333.     jne    sw11
  334.     or    dh,bysize
  335. sw11:    cmp    al,'H'                  ; Hidden?
  336.     jne    sw12
  337.     or    dh,byhide
  338. sw12:    cmp    al,'M'                  ; Modified only
  339.     jne    sw12b
  340.     or    dl,bymod
  341. sw12b:    cmp    al,'W'                  ; Wait when screen fills?
  342.     jne    sw12c
  343.     or    dl,bywait
  344. sw12c:    cmp    al,'F'                  ; Sort by filename?
  345.     jne    sw12d
  346.     or    dh,byname
  347. sw12d:    cmp    al,'N'                  ; No sorting?
  348.     jne    sw13
  349.     and    dh,0ffh-byname-byext-bysize-bydate
  350.  
  351. sw13:    jmp    sw2            ; Try for another option
  352.  
  353. switchs endp
  354.     page
  355. ;
  356. ;    Copy command parameters
  357.  
  358. getparm proc    near
  359.     mov    si,82h            ; Command tail
  360.     mov    di,offset parmdir    ; goes after d:\
  361.     sub    cx,cx            ;
  362.     or    cl,byte ptr -2[si]    ; any parmeters?
  363.     jz    parm9            ; no, use defaults
  364.  
  365. parm0:    cmp    byte ptr 1[si],':'      ; Drive specified?
  366.     jne    parm1            ;  no
  367.     mov    di,offset parmdr    ;  yes, replace drive letter
  368.  
  369. parm1:    lodsb                ; Skip leading blanks
  370.     cmp    al,' '                  ;
  371.     jne    parm3            ;
  372.     loope    parm1            ;
  373.     jcxz    parm9            ;
  374.  
  375. parm2:    lodsb                ; Copy d:\path\fname.ext
  376. parm3:    cmp    al,cr            ; end of string?
  377.     je    parm9            ;
  378.     cmp    al,' '                  ; end of operand?
  379.     jbe    parm9            ;
  380.     cmp    al,','                  ;
  381.     je    parm9            ;
  382.     stosb                ;
  383.     loop    parm2            ;
  384.  
  385. parm9:    and    parmdr,0dfh        ; Upper case drive parm
  386.     mov    drptr,di        ; Save ptr to parm end
  387.     mov    al,0            ; Insure asciiz
  388.     stosb                ;
  389.     mov    al,parmdr        ;
  390.     mov    origdr,al        ;
  391.     mov    rootdir,al        ;
  392.     ret                ;
  393. getparm endp
  394.     page
  395. ;
  396. ;    Get volume label and disk free space
  397.  
  398. getvol    proc    near
  399.     mov    dl,parmdr        ; Get drive letter
  400.     sub    dl,64            ; and make it a number
  401.     mov    drivenr,dl        ;
  402.     mov    si,offset origdir+1    ; Save current path name
  403.     mov    ah,getpath        ;
  404.     int    21h            ;
  405.  
  406.     mov    al,0            ; Get end of path name
  407.     mov    di,offset origdir    ;
  408.     mov    cx,67            ;
  409.     repne    scasb            ;
  410.     sub    di,2            ;
  411.     mov    origptr,di        ;
  412.  
  413.     cmp    origdir+1,0        ; Already in root?
  414.     je    getvl3            ; yes, no chdir needed
  415.     inc    origptr         ;
  416.     mov    dx,offset rootdir    ; no, point to root directory
  417.     mov    ah,chdir        ;
  418.     int    21h            ;
  419.     jc    getvl9            ;
  420.  
  421. getvl3: mov    dx,offset extfcb    ; Search for volume entry
  422.     mov    ah,11h            ;
  423.     int    21h            ;
  424.  
  425.     or    al,al            ; Any found?
  426.     jnz    getvl4            ; no, tough
  427.     mov    cx,11            ; yes, copy it to heading
  428.     mov    si,offset dta+8     ;
  429.     mov    di,offset volname    ;
  430.     repz    movsb            ;
  431.  
  432. getvl4: cmp    origdir+1,0        ; Need to restore curdir?
  433.     je    getvl9            ;
  434.     mov    dx,offset origdr    ; Back to current dir
  435.     mov    ah,chdir        ;
  436.     int    21h            ;
  437.  
  438. getvl9:                 ; Get disk free space
  439.     mov    dl,parmdr        ; Current drive letter
  440.     sub    dl,64            ;  as a number
  441.     mov    ah,dskspc        ; Get free space
  442.     int    21h            ;
  443.     cmp    ax,0ffffh        ; Valid?
  444.     je    getvl10         ; no, skip it
  445.     mul    cx            ;  Bytes per cluster
  446.     mul    bx            ;  Total free
  447.     mov    si,offset nrsize    ; Point to msg
  448.     call    format            ;
  449. getvl10:
  450.     ret                ;
  451. getvol    endp                ;
  452.     page
  453. ;
  454. ;    Set search criteria
  455.  
  456. setarg    proc    near
  457. set1:    mov    bp,offset dta        ; First DTA
  458.     mov    bx,offset search    ; Search arument entries
  459.  
  460.     mov    ax,word ptr parmdr    ; Set search drive
  461.     lea    di,[bx].argdriv     ;
  462.     stosw                ;
  463.  
  464. ;    parameter is possibly a filespec
  465.  
  466. set2:    cmp    byte ptr parmdir,'\'    ; path requested?
  467.     je    set8            ; yes, more than a filespec
  468.     mov    cx,origptr        ; no, set search path
  469.     mov    si,offset origdr+2    ;  from original path
  470.     sub    cx,si            ;
  471.     jcxz    set2a            ; In a subdir?
  472.     rep    movsb            ;
  473.     mov    al,'\'                  ; Add filespec delimiter
  474.     stosb                ;
  475.  
  476. set2a:    mov    si,offset parmdir    ; Copy filespec
  477.     mov    cx,drptr        ;  to search criteria
  478.     sub    cx,si            ;
  479.     jcxz    set5            ; None, append global filespec
  480.     rep    movsb            ;
  481.     jmp    set7            ; Done
  482.  
  483. ;    parameter is possibly a path\filespec
  484.  
  485. set8:    mov    dx,offset parmdr    ; Requested d:\path\filespec
  486.     mov    ah,chdir        ;
  487.     int    21h            ; Is parm a valid path name?
  488.     jc    set4            ;  no, have d:\path\filespec
  489.  
  490. set8a:    mov    dx,offset origdr    ; Restore path
  491.     mov    ah,chdir        ;
  492.     int    21h            ;
  493.  
  494.     mov    si,offset parmdir    ; Set search d:\path
  495.     mov    cx,drptr        ;  from command parameter
  496.     sub    cx,si            ;
  497.     jcxz    set5            ;
  498.     rep    movsb            ;
  499.     jmp    set5            ; Append global filespec
  500.  
  501. set4:    mov    si,offset parmdir    ; Set search d:\path
  502.     mov    cx,drptr        ;  from command parameter
  503.     sub    cx,si            ;
  504. set4a:    jcxz    set5            ;
  505.     rep    movsb            ;
  506.     jmp    set7            ; Done
  507.  
  508. ;    append global filespec to search criteria
  509.  
  510. set5:    mov    si,offset anyname    ; Add global search arg
  511.     cmp    byte ptr -1[di],'\'     ; Already have delimiter?
  512.     jne    set6            ;
  513.     dec    di            ; yes, overlay it
  514.  
  515. set6:    mov    cx,15            ; Length of global filespec
  516.     push    di            ; Save current end pointer
  517.     rep    movsb            ;
  518.     pop    di            ; Restore work reg
  519.     jmp    set9            ;
  520.  
  521. set7:    mov    al,0            ; Append ASCIIZ stopper
  522.     stosb                ;
  523.  
  524. set9:    lea    si,[bx].argdriv     ; Copy d:\path\filespec
  525.     mov    cx,di            ;
  526.     sub    cx,si            ;
  527.     mov    di,offset titles    ;  to titles
  528.     rep    movsb            ;
  529.     mov    byte ptr [di],stopper    ; Add print stopper
  530.  
  531. set10:    ret                ; Back to caller
  532.  
  533. setarg    endp
  534.     page
  535. ;
  536. ;    Obtain directory table
  537.  
  538. alloc    proc    near
  539.     push    bx            ; save registers
  540.     mov    bx,pgmsize        ; size of program module
  541.     mov    ah,4ah            ; modify memory
  542.     int    21h            ;
  543.     mov    bx,-1            ; ask for all remaining memory
  544. alloc1:
  545.     mov    ah,48h            ; allocate memory
  546.     int    21h            ;
  547.     jc    alloc1            ; get what there is
  548.  
  549.     mov    segdir,ax        ; segment addr of table
  550.     mov    nxtdir,0        ; offset to first entry
  551.  
  552.     shr    bx,1            ; change number of paragraphs
  553.     shr    bx,1            ;  to 64-byte entries
  554.     mov    maxdir,bx        ; maximum table count
  555.     pop    bx            ; restore registers
  556.     ret                ;
  557. alloc    endp
  558.  
  559.     page
  560. ;
  561. ;    Build table of directory entries
  562.  
  563. getdir    proc    near
  564.     push    bp            ; Ptr to DTA
  565.     push    bx            ; Ptr to search are
  566.  
  567. ; Set DTA for current nesting level
  568.     mov    dx,bp            ; Data transfer area
  569.     mov    ah,setdta        ; Set local DTA
  570.     int    21h
  571.  
  572. ; Set search criteria for this level
  573.     mov    dx,bx            ; Search criteria
  574.     sub    cx,cx            ; Directory options
  575.     mov    cl,dirmask
  576.     mov    ah,4eh            ; Find first matching entry
  577.     int    21h
  578.  
  579. ; Examine directory entry just returned
  580. get1:    or    al,al
  581.     jnz    gotdir            ; Not found, quit looking.
  582.     cmp    byte ptr [bp].dtaattr,10h
  583.     jne    get3            ; Is it a sub-dir?
  584.     cmp    byte ptr [bp].dtaname,'.'
  585.     je    get4            ; May be <DIR> entry
  586.  
  587.     call    addfile         ; Add directory entry to table
  588.  
  589. ; Build parms for sub-dir search
  590.     lea    dx,[bp].dtaname     ; Save ptr to found name
  591.     lea    si,[bx].argdriv     ; Point to current arg
  592.     add    bp,dta_len        ; Next DTA
  593.     add    bx,arg_len        ; Next search arg
  594.  
  595. ; Copy previous arg as next search arg
  596.     mov    cx,64            ; Maximum length
  597.     lea    di,[bx].argdriv     ; Point to new search arg
  598. get6:    lodsb                ;
  599.     cmp    al,'?'                  ; Used global name?
  600.     je    get9            ;  yes, single nest
  601.     cmp    al,0            ; End of dir name?
  602.     je    get5            ;  yes, append wild cards
  603.     stosb                ;
  604.     loop    get6            ; Continue copying
  605.  
  606. ; Add sub-dir name to search arg
  607. get9:    mov    si,dx            ; Saved ptr to found name
  608. get8:    lodsb                ;
  609.     cmp    al,0            ; End of DIR name?
  610.     je    get5            ;  yes, append wild cards
  611.     stosb                ;  no, add to arg
  612.     loop    get8            ; Continue copying fname
  613.  
  614. get5:    mov    si,offset anyname    ; Append wild cards
  615.     rep    movsb            ;
  616.  
  617.     call    getdir            ; Search the sub-dir
  618.     sub    bx,arg_len        ; restore arg
  619.     sub    bp,dta_len        ; and DTA
  620.  
  621. ; Restore DTA to find next matching entry
  622.     mov    dx,bp            ; Data transfer area
  623.     mov    ah,setdta        ; Set DTA
  624.     int    21h            ;
  625.     jmp    short get4        ;
  626.  
  627. get3:    call    addfile         ; Add the entry
  628.  
  629. get4:    mov    cx,12            ; Clear found name
  630.     mov    al,' '                  ;
  631.     lea    di,[bp].dtaname     ; Point to file name area
  632.     rep    stosb            ;
  633.  
  634.     mov    ah,4fh            ; Search for next file
  635.     mov    dx,bp            ;
  636.     int    21h            ;
  637.     jmp    get1            ; Loop for next one
  638.  
  639. gotdir: pop    bx            ; Restore arg
  640.     pop    bp            ;  and DTA
  641.     ret                ; Return to caller
  642. getdir    endp                ;
  643.     page
  644. ;
  645. ;    Add a directory entry to table
  646.  
  647. addfile proc    near
  648.     save    <cx,bp,di,si>        ; Save registers
  649.  
  650.     mov    cx,tbl_len        ; Initialize table entry
  651.     mov    si,offset model     ;
  652.     mov    di,offset pline     ;
  653.     rep    movsb            ;
  654.  
  655.     mov    al,[bp].dtaattr     ; Copy file attributes
  656.     mov    pline.tblattr,al    ;
  657.     test    flags2,bymod        ; Just modified files?
  658.     jz    addfile1        ;  no, add all
  659.     test    al,10h            ;  yes, pass subdirs
  660.     jnz    addfile1        ;
  661.     test    al,20h            ; is it modified tho?
  662.     jnz    addfile1        ; yes, add the entry
  663.     jmp    addfile11        ; no, exit
  664.  
  665. addfile1:
  666.     call    getdate         ; Format date
  667.     call    gettime         ;  time
  668.     call    getsize         ;  bytes
  669.  
  670.     lea    si,[bp].dtaname     ; Copy file name
  671.     lea    di,pline.tblname    ;
  672.     mov    cx,12            ;
  673. addfile2:
  674.     lodsb                ;
  675.     cmp    al,0            ;
  676.     je    addfile5        ;
  677.     cmp    al,'.'                  ; separate extension
  678.     je    addfile3        ;
  679.     stosb                ;
  680.     loop    addfile2        ;
  681. addfile3:
  682.     jcxz    addfile5        ;
  683.     lea    di,pline.tblname+8    ;
  684. addfile4:
  685.     stosb                ;
  686.     lodsb                ;
  687.     cmp    al,0            ;
  688.     je    addfile5        ;
  689.     loop    addfile4        ;
  690.  
  691. addfile5:
  692.     lea    di,pline.tblpath    ; Copy path name
  693.     lea    si,[bx].argname     ;
  694.     mov    cx,size tblpath     ;
  695. addfile6:
  696.     cmp    byte ptr 1[si],'?'      ; Wildcard part?
  697.     je    addfile7        ; yes, have name
  698.     lodsb                ;
  699.     stosb                ;
  700.     loop    addfile6        ;
  701.  
  702. addfile7:
  703.     lea    si,pline.tblname    ;
  704.     test    pline.tblattr,10h    ; Subdirectory?
  705.     jnz    addfile8        ;  yes, copy path name
  706.     jcxz    addfile10        ;  no, pad with blanks
  707.     mov    al,' '                  ;
  708.     rep    stosb            ;
  709.     jmp    addfile10        ;
  710.  
  711. addfile8:
  712.     cmp    cl,12            ; Max subdir name length
  713.     jbe    addfile9        ; to be copied
  714.     mov    cl,12            ;
  715. addfile9:
  716.     rep    movsb            ;
  717.  
  718. addfile10:
  719.     mov    cx,numdir        ; Number of table entries
  720.     cmp    cx,maxdir        ; is table full?
  721.     jae    addfile11        ;  yes, skip it
  722.     push    es            ;  no, add to table
  723.     mov    ax,word ptr segdir    ; Segment addr of table
  724.     add    ax,nxtdir        ; plus next entry offset
  725.     sub    di,di            ;
  726.     mov    si,offset pline     ; copy table stuff
  727.     mov    cx,tbl_len        ;
  728.     mov    es,ax            ; Set target segment
  729.     rep    movsb            ;
  730.     pop    es            ;
  731.  
  732.     inc    numdir            ; Incr entry count
  733.     add    nxtdir,tblpara        ; Bump offset for next table entry
  734.  
  735. addfile11:
  736.     return    <si,di,bp,cx>        ; restore registers
  737. addfile endp
  738.     page
  739. ;
  740. ;    Print file information
  741.  
  742. print    proc    near
  743.     cmp    numdir,1        ; Just one file?
  744.     ja    printt            ;  no, two up heading
  745.     mov    word ptr titled,0a0dh    ;
  746.     mov    titled+2,stopper    ;
  747.  
  748. printt:
  749.     mov    dx,offset titlea    ; Top titles
  750.     call    prints            ;
  751.     mov    dx,offset titleb    ; Subdir name
  752.     call    prints            ;
  753.     mov    dx,offset titlec    ; Headings
  754.     call    prints            ;
  755.  
  756.     mov    ax,cs            ; Set extra seg
  757.     mov    es,ax            ;  locally
  758.  
  759.     sub    ax,ax            ; Offset to first table entry
  760.     mov    nxtdir,ax        ;  as current entry
  761.     mov    ax,numdir        ; Compute offset
  762.     inc    ax            ;  to second half
  763.     shr    ax,1            ;
  764.     mov    cl,2            ; Times 64 (4 paras each)
  765.     shl    ax,cl            ;
  766.     mov    cx,numdir        ; Number of entries
  767.     or    cx,cx            ; Even number of entries?
  768.     jz    print7            ; yes, all set
  769.     inc    cx            ; no, just one
  770.     shr    cx,1            ; Set half of count
  771.  
  772. print_next:
  773.     call    print0            ; Left side
  774.     push    [nxtdir]        ;
  775.     add    nxtdir,ax        ;
  776.     call    print0            ; Right side
  777.     pop    [nxtdir]        ;
  778.  
  779.     add    nxtdir,tblpara        ; Point to next entry
  780.  
  781.     test    flags2,bywait        ; Wait for screen full?
  782.     jz    printw1         ;  no, continue
  783.     inc    linecnt         ;  yes, bump line count
  784.     mov    dl,_rows        ; rows available on screen
  785.     dec    dl            ; leave room for headings
  786.     cmp    linecnt,dl        ; Full now?
  787.     jb    printw1         ;  no, continue
  788.     call    waitkey         ;  yes, get a key
  789.  
  790. printw1:
  791.     loop    print_next        ; continue for all entries
  792. print7:
  793.     ret                ; done, return
  794. print    endp                ;
  795.  
  796.  
  797. print0    proc    near
  798.     save    <ax,cx,di>        ; Save registers
  799.  
  800.     push    ds            ; copy table entry to print line
  801.     mov    cx,tbl_len        ; length of table entry
  802.     sub    si,si            ; offset to next entry
  803.     mov    di,offset pline     ; offset to print line
  804.     mov    ax,word ptr segdir    ; Segment addr for table
  805.     add    ax,nxtdir        ;  plus paras offset
  806.     mov    ds,ax            ;   as source segment
  807.     rep    movsb            ;    for copy
  808.     pop    ds            ;
  809.  
  810.     inc    count            ; Number of files
  811.     mov    ax,count        ;
  812.     cmp    ax,numdir        ; Done em all?
  813.     jbe    print1            ; no, display this one
  814.     dec    count            ; yes,
  815.     jmp    print9            ;  done, return
  816.  
  817. print1:
  818.     mov    cl,byte ptr pline.tblattr
  819.     lea    di,byte ptr pline.tblfatr
  820.  
  821.     test    cl,32            ; Archived?
  822.     jnz    print2            ;
  823.     mov    al,'A'                  ;
  824.     stosb                ;
  825.  
  826. print2: test    cl,4            ; System?
  827.     jz    print3            ;
  828.     mov    al,'S'                  ;
  829.     stosb                ;
  830.  
  831. print3: test    cl,2            ; Hidden?
  832.     jz    print4            ;
  833.     mov    al,'H'                  ;
  834.     stosb                ;
  835.  
  836. print4: test    cl,1            ; Read only?
  837.     jz    print5            ;
  838.     mov    al,'R'                  ;
  839.     stosb                ;
  840.  
  841. print5: test    cl,10h            ; Sub directory?
  842.     jz    print5a         ; no
  843.     lea    di,pline.tblfatr-1    ; yes, special display
  844.     mov    si,offset subdir    ;
  845.     mov    cx,4            ;
  846.     rep    movsb            ;   for copying
  847.  
  848. print5a:
  849.     test    flags2,bypath        ; Doing all paths?
  850.     jz    print6            ;
  851.     cmp    pline.tblpath+1,'?'     ; Nested entry?
  852.     je    print6            ;  no, as-is
  853.     mov    pline.tblfatr-1,'-'     ;  yes, flag it in display
  854.  
  855. print6: lea    si,pline.tbldate    ; Reformat date
  856.     mov    di,offset olddate    ;   for copying
  857.     mov    cx,8            ;
  858.     rep    movsb            ;
  859.  
  860.     lea    di,pline.tbldate    ; Format date
  861.     mov    ax,word ptr olddate+3    ;
  862.     stosw                ;
  863.     mov    al,"/"                  ;
  864.     stosb                ;
  865.     mov    ax,word ptr olddate+6    ;
  866.     stosw                ;
  867.     mov    al,"/"                  ;
  868.     stosb                ;
  869.     mov    ax,word ptr olddate    ;
  870.     stosw                ;
  871.  
  872.     cmp    pline.tblext,' '        ; Any extension?
  873.     jne    print8            ;  yes, leave the dot
  874.     mov    pline.tblext-1,' '      ;  no, rid it
  875.  
  876. print8: lea    dx,pline.tblname    ;
  877.     mov    byte ptr pline.tblctl,' '
  878.     mov    byte ptr pline.tblctl+1,stopper
  879.     mov    nrmsg+1,lf        ;
  880.     test    count,1         ; Right side?
  881.     jnz    print8a         ;
  882.     mov    nrmsg+1,cr        ;
  883.     mov    word ptr pline.tblctl,0a0dh
  884. print8a:
  885.     call    prints            ; Display an entry
  886.  
  887. print9:
  888.     return    <di,cx,ax>        ; Restore registers
  889. print0    endp
  890.  
  891.     page
  892. ;
  893. ;    Pause at end of screen for any key
  894.  
  895. waitkey proc    near
  896.     save    <ax,bx,cx,dx>        ; save work regs
  897.  
  898.     mov    linecnt,0        ; reset counter
  899.     mov    ah,2            ; Set cursor position
  900.     mov    dl,0            ;  col 72
  901.     mov    dh,_rows        ;  last row
  902.     add    dh,2            ; adjust for heading
  903.     sub    bx,bx
  904.     int    10h
  905.  
  906.     mov    dx,offset more        ; ask for more
  907.     call    prints            ;
  908.  
  909.     mov    ah,0            ; wait for a key
  910.     int    16h            ;
  911.  
  912.     mov    dx,offset backsp    ; backspace over 'more...'
  913.     call    prints            ;
  914.  
  915.     test    flags,byclear        ; Clear screen each time?
  916.     jz    waitkeyc        ;  no
  917.     call    cls            ; Clear screen
  918. waitkeyc:
  919.     mov    dx,offset titlea    ; Top titles
  920.     call    prints            ;
  921.     mov    dx,offset titleb    ; Subdir name
  922.     call    prints            ;
  923.     mov    dx,offset titlec    ; Headings
  924.     call    prints            ;
  925.  
  926. waitkeyx:
  927.     return    <dx,cx,bx,ax>        ; restore registers
  928. waitkey endp
  929.     page
  930. ;
  931. ;    Format the date
  932.  
  933. getdate proc    near            ;Format the date
  934.     mov    ax,word ptr [bp].dtadate
  935.     mov    di,offset pline.tbldate
  936.     or    ax,ax            ;Is it zero?
  937.     jz    gotdate
  938.     push    ax            ;Save date
  939.     and    ax,mask yr        ;Get year part
  940.     mov    cl,yr            ;Bits to shift
  941.     call    cnvrt
  942.     or    al,'8'                  ;Adjust for base year
  943.     stosw
  944.     mov    al,'-'
  945.     stosb
  946.  
  947.     pop    ax            ;Get the date back
  948.     push    ax            ;Save it
  949.     and    ax,mask mo        ;Get month part
  950.     mov    cl,mo            ;Bits to shift
  951.     call    cnvrt2
  952.     stosw
  953.     mov    al,'/'
  954.     stosb
  955.  
  956.     pop    ax            ;Get the date back
  957.     and    ax,mask dy        ;Get day part
  958.     mov    cl,dy            ;Bits to shift
  959.     call    cnvrt
  960.     stosw
  961. gotdate:ret
  962. getdate endp
  963.  
  964.     page
  965. ;
  966. ;    Format the time
  967.  
  968. gettime proc    near            ; Format the date
  969.     mov    ax,word ptr [bp].dtatime;
  970.     lea    di,pline.tbltime    ;
  971.     or    ax,ax            ; It is zero?
  972.     jz    gottime         ;
  973.     push    ax            ; Save date
  974.     and    ax,mask hour        ; Get hour part
  975.     mov    cl,hour         ; Bits to shift
  976.     shr    ax,cl            ;
  977.     call    cnvrt1            ;
  978.     stosw                ;
  979.     mov    al,':'                  ;
  980.     stosb                ;
  981.  
  982. gt3:    pop    ax            ; Get the time back
  983.     and    ax,mask min        ; Get min part
  984.     mov    cl,min            ; Bits to shift
  985.     call    cnvrt            ;
  986.     stosw                ;
  987. gottime:
  988.     ret                ;
  989. gettime endp
  990.  
  991. cnvrt2    proc    near            ; Convert to ASCII
  992.     call    cnvrt            ;
  993.     cmp    al,'0'                  ; Suppress leading zero
  994.     jne    cnvrtd            ;
  995.     mov    al,' '                  ;
  996.     ret                ;
  997.  
  998. cnvrt:    shr    ax,cl            ;
  999. cnvrt1: aam                ; Make AL into BCD
  1000.     or    ax,'00'                 ; and to ASCII
  1001.     xchg    al,ah            ;
  1002. cnvrtd: ret                ;
  1003. cnvrt2    endp                ;
  1004.     page
  1005. ;
  1006. ;    Format the size
  1007.  
  1008. getsize proc    near
  1009.     save    <bp,bx>         ; Ptr to Dta entry
  1010.     mov    ax,word ptr [bp].dtasize;
  1011.     add    numbyte+2,ax        ;
  1012.     mov    dx,word ptr [bp].dtasize+2
  1013.     adc    numbyte,dx        ;
  1014.     lea    si,pline.tblsize    ; Target offset
  1015.     call    format            ; Format double word
  1016.     return    <bx,bp>         ;
  1017. getsize endp
  1018.  
  1019.     page
  1020. ;
  1021. ;    Format ASCII numbers from binary
  1022.  
  1023. format    proc    near            ; Formats a 32 bit integer in DX:AX
  1024.     save    <bp,bx,di,si>        ; to DS:SI
  1025.     mov    ddptr,si        ; addr of target field
  1026.     mov    di,dx            ; subroutine uses di:si
  1027.     mov    si,ax
  1028.     call    printdd
  1029.     return    <si,di,bx,bp>
  1030.  
  1031. printdd:
  1032.     xor    ax,ax        ;zero out the
  1033.     mov    bx,ax        ; working
  1034.     mov    bp,ax        ; registers.
  1035.     mov    cx,32        ;# bits of precision
  1036. j1:    shl    si,1
  1037.     rcl    di,1
  1038.     xchg    bp,ax
  1039.     call    j6
  1040.     xchg    bp,ax
  1041.     xchg    bx,ax
  1042.     call    j6
  1043.     xchg    bx,ax
  1044.     adc    al,0
  1045.     loop    j1
  1046.     mov    cx,1710h
  1047.     mov    ax,bx
  1048.     call    j2
  1049.     mov    ax,bp
  1050. j2:    push    ax
  1051.     mov    dl,ah
  1052.     call    j3
  1053.     pop    dx
  1054. j3:    mov    dh,dl
  1055.     shr    dl,1        ;move high
  1056.     shr    dl,1        ; nibble to
  1057.     shr    dl,1        ; the low
  1058.     shr    dl,1        ; position.
  1059.     call    j4
  1060.     mov    dl,dh
  1061. j4:    and    dl,0fh        ;mask low nibble
  1062.     jz    j5        ;if not zero
  1063.     sub    cl,cl
  1064. j5:    dec    ch
  1065.     and    cl,ch
  1066.     or    dl,'0'          ;fold in ascii zero
  1067.     sub    dl,cl
  1068.     mov    bx,ddptr
  1069.     mov    [bx],dl     ;ptr to next target field
  1070.     inc    ddptr
  1071.     ret
  1072.  
  1073. j6:    adc    al,al
  1074.     daa
  1075.     xchg    al,ah
  1076.     adc    al,al
  1077.     daa
  1078.     xchg    al,ah
  1079.     ret
  1080.  
  1081.  
  1082. format    endp
  1083.     page
  1084. ;
  1085. ;    Print String like INT 21H function 9
  1086.  
  1087. prints    proc    near            ; DX has offset to string
  1088.     save    <si,bx,cx>        ;  ending in char x'FF'
  1089.     mov    si,dx            ; Ptr to string text
  1090.     sub    cx,cx            ; Overall text length
  1091. ps1:    lodsb
  1092.     cmp    al,stopper        ; Ending hex FF?
  1093.     je    ps9
  1094.     inc    cx
  1095.     jmp    short ps1
  1096.  
  1097. ps9:
  1098.     mov    bx,1            ; Standard output device
  1099.     mov    ah,40h            ;  to write to
  1100.     int    21h
  1101.  
  1102.     return    <cx,bx,si>        ; Recover registers
  1103. prints    endp
  1104.  
  1105.  
  1106. cls    proc    near            ; Clear screen
  1107.     save    <ax,bx,cx,dx,si>
  1108.  
  1109.     mov    ax,600h         ; Scroll all lines
  1110.     sub    cx,cx            ;  upper left
  1111.     mov    dx,184fh        ;  lower right
  1112.     mov    bl,_page        ;  video page
  1113.     mov    bh,_attr        ;  attribute
  1114.     int    10h            ; Video I/O
  1115.  
  1116.     mov    bl,_attr        ; Set cursor position
  1117.     mov    bh,_page
  1118.     sub    dx,dx            ;  to 1,1
  1119.     mov    ah,2
  1120.     int    10h
  1121.  
  1122.     return    <si,dx,cx,bx,ax>    ; return to caller
  1123. cls    endp
  1124.  
  1125.     page
  1126. ;
  1127. ;    Format current date and time
  1128.  
  1129. clock    proc    near
  1130.     save    <ax,bx,cx,dx>        ; save work regs
  1131.  
  1132.     mov    ah,2ah            ;Get date
  1133.     int    21h
  1134.     sub    cx,1900         ; last two digits
  1135.     mov    ax,cx            ;Make readable
  1136.     call    cnvrt1            ;Convert to ASCII
  1137.     mov    word ptr year,ax
  1138.     xchg    al,dh            ;Get month
  1139.     call    cnvrt1            ;Convert to ASCII
  1140.     mov    word ptr month,ax
  1141.     xchg    al,dl            ;Get day
  1142.     call    cnvrt1            ;Convert to ASCII
  1143.     mov    word ptr day,ax
  1144.  
  1145.     mov    ah,2ch            ;Get time
  1146.     int    21h
  1147.     xchg    al,ch            ;Get hours
  1148.     call    cnvrt1            ;Convert to ASCII
  1149.     mov    word ptr hours,ax
  1150.     xchg    al,cl            ;Get minutes
  1151.     call    cnvrt1            ;Convert to ASCII
  1152.     mov    word ptr mins,ax
  1153.     xchg    al,dh            ;Get seconds
  1154.     call    cnvrt1            ;Convert to ASCII
  1155.     mov    word ptr secs,ax
  1156.  
  1157.     return    <dx,cx,bx,ax>        ; return to caller
  1158. clock    endp
  1159.  
  1160.     page
  1161. ;
  1162. ;    Shell-Metzger Sort of 64-byte table records
  1163.  
  1164. ;    Variables used for sort subroutine
  1165.  
  1166. numrec    dw    0            ; Number of entries
  1167. loc    dw    0
  1168. index1    dw    0
  1169. incr    dw    0
  1170. limit    dw    0
  1171. index2    dw    0
  1172. ptr1    dw    0            ;Offset to record Index1
  1173. ptr2    dw    0            ;Offset to record Index2
  1174.  
  1175. keyptr    dw    0            ;Offset to key
  1176. keylen    dw    0            ;Length of key
  1177. base    dw    0            ;Seg addr of array
  1178.  
  1179. sort    proc    near
  1180.     push    ds            ; Save seg regs
  1181.     push    es
  1182.  
  1183. ;    Set sort options
  1184.  
  1185.     sub    bx,bx            ; Offset to key
  1186.     mov    bl,offset tblpath
  1187.     test    flags,bysize
  1188.     jz    sort1
  1189.     mov    bl,offset tblsize    ; Sort by size
  1190. sort1:    test    flags,bydate
  1191.     jz    sort2
  1192.     mov    bl,offset tbldate    ; Sort by date/time
  1193. sort2:    test    flags,byext
  1194.     jz    sort3
  1195.     mov    bl,offset tblext
  1196.  
  1197. ;    Initialize sort parameters
  1198.  
  1199. sort3:    mov    cx,numdir        ; Number of entries
  1200.     mov    numrec,cx
  1201.     mov    keyptr,bx
  1202.  
  1203.     mov    dx,64            ; Length of key
  1204.     sub    dx,bx
  1205.     mov    keylen,dx
  1206.     mov    es,segdir        ; Seg addr of table
  1207.     mov    ax,es            ; Save array addr
  1208.     sub    ax,4            ;  adjust for indexing
  1209.     mov    base,ax
  1210.  
  1211. ;    Sort 64-byte entries
  1212.  
  1213.     mov    loc,cx            ; Loc=NumRecs
  1214.  
  1215. check:    cmp    loc,1            ; IF Loc<=1 THEN
  1216.     jg    check1            ; GOTO SORTED
  1217.     jmp    sorted
  1218.  
  1219. check1: mov    ax,loc
  1220.     sar    ax,1            ; Loc=2*(Loc/4)+1
  1221.     or    ax,1
  1222.     mov    loc,ax
  1223.  
  1224.     mov    ax,numrec        ; Limit=NumRec-Loc
  1225.     sub    ax,loc
  1226.     mov    limit,ax
  1227.  
  1228.     mov    incr,0            ; Incr=0
  1229.  
  1230. again:    inc    incr            ; Incr=Incr+1
  1231.  
  1232.     mov    ax,incr         ; IF Incr>Limit THEN GOTO CHECK
  1233.     cmp    ax,limit
  1234.     jg    check
  1235.  
  1236.     shl    ax,1
  1237.     shl    ax,1
  1238.     mov    index1,ax        ; Index1=Incr
  1239.  
  1240.     mov    index2,ax        ; Index2=Index1+Loc
  1241.     mov    ax,loc
  1242.     shl    ax,1            ; times 2
  1243.     shl    ax,1            ; times 4
  1244.     add    index2,ax
  1245.  
  1246. comp:    mov    ax,index1        ; IF array(Index1)<=array(Index2)
  1247.     add    ax,base
  1248.     mov    es,ax
  1249.     mov    ptr1,ax
  1250.     mov    di,keyptr
  1251.  
  1252.     mov    ax,index2        ; THEN GOTO AGAIN
  1253.     add    ax,base
  1254.     mov    ptr2,ax
  1255.     mov    si,keyptr
  1256.     mov    cx,cs:keylen
  1257.  
  1258.     push    ds
  1259.     mov    ds,ax
  1260.     repe    cmpsb
  1261.     pop    ds
  1262.     jae    again
  1263.  
  1264. swap:    mov    bx,ptr1         ; ELSE
  1265.     mov    dx,ptr2         ; TEMP=array(Index1)
  1266.  
  1267.     mov    ax,cs
  1268.     mov    es,ax
  1269.     mov    di,offset temp
  1270.     mov    cx,tbl_len
  1271.  
  1272.     mov    ds,bx
  1273.     sub    si,si
  1274.     rep    movsb
  1275.  
  1276.     mov    es,bx            ; array(Index1)=array(Index2)
  1277.     mov    ds,dx
  1278.     sub    di,di
  1279.     sub    si,si
  1280.     mov    cx,tbl_len
  1281.     rep    movsb
  1282.  
  1283.     mov    ax,cs            ; array(Index2)=TEMP
  1284.     mov    ds,ax
  1285.     mov    si,offset temp
  1286.     mov    es,dx
  1287.     sub    di,di
  1288.     mov    cx,tbl_len
  1289.     rep    movsb
  1290.  
  1291.     mov    ax,index1        ; Index2=Index1
  1292.     mov    index2,ax
  1293.  
  1294.     mov    ax,loc            ; Index1=Index1-Loc
  1295.     shl    ax,1
  1296.     shl    ax,1
  1297.     sub    index1,ax
  1298.  
  1299.     jg    comp            ; IF Index1>0 then GOTO COMP
  1300.     jmp    again            ; ELSE GOTO AGAIN
  1301.  
  1302. sorted: pop    es            ;Recover register
  1303.     pop    ds
  1304.     ret
  1305. sort    endp
  1306.  
  1307.     page
  1308. ;
  1309. ;    Usage information, display panel
  1310.  
  1311. help    db    cr,lf,tab,tab,' -- LDIR Version 4.1 --- 25 Jan 89 --'
  1312.     db    cr,lf,tab,tab,'  (c) Copyright Vernon D. Buerg 1986-89'
  1313.     db    cr,lf
  1314.     db    cr,lf,tab,tab,tab,' Command syntax:'
  1315.     db    cr,lf
  1316.     db    cr,lf,tab,tab,'LDIR [d:][\path[fname[.ext]]] /?.../?'
  1317.     db    cr,lf,tab,tab
  1318.     db    cr,lf,tab,tab,'    /A   include Attributes'
  1319.     db    cr,lf,tab,tab,'    /C   Clear screen first'
  1320.     db    cr,lf,tab,tab,'    /D   sort by Date'
  1321. ;    Db    CR,LF,TAB,TAB,'    /F   sort by Filename (default)'
  1322.     db    cr,lf,tab,tab,'    /H   include Hidden files'
  1323.     db    cr,lf,tab,tab,'    /M   only Modified files'
  1324.     db    cr,lf,tab,tab,'    /N   No sorting'
  1325.     db    cr,lf,tab,tab,'    /P   include all Paths'
  1326.     db    cr,lf,tab,tab,'    /S   sort by Size'
  1327.     db    cr,lf,tab,tab,'    /W   Wait after screen full'
  1328.     db    cr,lf,tab,tab,'    /X   sort by eXtension'
  1329.     db    stopper
  1330. ;    Db    CR,LF,TAB,TAB,'    /?   display usage syntax',Stopper
  1331.  
  1332.  
  1333. ;
  1334. ;    Data structures and work areas
  1335.  
  1336.  
  1337. parmdr        db    ' :'                            ; Drive letter
  1338. parmdir     equ    $                ; for specific path
  1339.  
  1340. pline        equ    parmdir+64            ; Print line
  1341.  
  1342. dta        equ    pline+tbl_len            ; Disk transfer areas
  1343.  
  1344. search        equ    dta + (depth+1)*dta_len     ; Search arguments
  1345.  
  1346. local_stack    equ    search + (depth+1)*arg_len    ; Local stack
  1347. local_stack_end equ    local_stack+512
  1348.  
  1349. workend     equ    local_stack_end + 2        ; End of work areas
  1350.  
  1351. pgmsize     equ    (workend - cseg + 512) /16    ; Size of program
  1352.  
  1353. cseg        ends
  1354.         end    ldir
  1355.